package ar.uade.edu.fain.ad.server.dao.jpa;

import java.util.List;

import javax.persistence.PersistenceException;

import org.hibernate.Session;

import ar.uade.edu.fain.ad.server.business.Comanda;
import ar.uade.edu.fain.ad.server.business.Mesa;
import ar.uade.edu.fain.ad.server.business.Mozo;
import ar.uade.edu.fain.ad.server.business.Pedido;
import ar.uade.edu.fain.ad.server.business.Plato;
import ar.uade.edu.fain.ad.server.dao.MesaDAO;
import ar.uade.edu.fain.ad.server.dao.PedidoDAO;
import ar.uade.edu.fain.ad.server.dao.PlatoDAO;
import ar.uade.edu.fain.ad.server.dao.entity.ComandaEntity;
import ar.uade.edu.fain.ad.server.dao.entity.MesaEntity;
import ar.uade.edu.fain.ad.server.dao.entity.MozoEntity;
import ar.uade.edu.fain.ad.server.dao.entity.PedidoEntity;
import ar.uade.edu.fain.ad.server.dao.entity.PlatoEntity;

public class PedidoJpaDAO 
		extends GenericJpaDAO<Pedido, PedidoEntity, Long> 
		implements PedidoDAO {

	private MesaDAO mesaDAO;

	private PlatoDAO platoDAO;

	public PedidoJpaDAO() {
		super(PedidoEntity.class);
	}

	public PlatoDAO getPlatoDAO() {
		return platoDAO;
	}

	public void setPlatoDAO(PlatoDAO platoDAO) {
		this.platoDAO = platoDAO;
	}

	public MesaDAO getMesaDAO() {
		return mesaDAO;
	}

	public void setMesaDAO(MesaDAO mesaDAO) {
		this.mesaDAO = mesaDAO;
	}

	@Override
	protected PedidoEntity toEntity(final Pedido business) {
		final Session session = getSession();
		PedidoEntity entity = null;
		if (business.getId() == null) {
			entity = new PedidoEntity();
		} else {
			 entity = (PedidoEntity) session.get(getType(), business.getId());	
		}
		entity.setEstadoPedido(business.getEstadoPedido());
		entity.setMesa((MesaEntity) 
				session.get(MesaEntity.class, business.getMesa().getId()));
		entity.setMozo((MozoEntity) 
				session.get(MozoEntity.class, business.getMozo().getId()));
		for (Comanda comanda : business.getComandas()) {
			ComandaEntity comandaEntity = null;
			if (comanda.getId() == null) {
				comandaEntity = new ComandaEntity();	
			} else {
				comandaEntity = (ComandaEntity) 
						session.get(ComandaEntity.class, comanda.getId());
			}
			comandaEntity.setCantidad(comanda.getCantidad());
			comandaEntity.setPlato((PlatoEntity) 
					session.get(PlatoEntity.class, comanda.getPlato().getId()));
			comandaEntity.setEstado(comanda.getEstado());
			entity.getComandas().add(comandaEntity);
		}
		return entity;
	}

	@Override
	protected Pedido toBusiness(final PedidoEntity entity) {
		Pedido business = new Pedido();
		business.setId(entity.getId());
		business.setEstadoPedido(entity.getEstadoPedido());
		Mesa mesa = getMesaDAO().get(entity.getMesa().getId());
		business.setMesa(mesa);
		Mozo mozo = new Mozo();
		mozo.setId(entity.getMozo().getId());
		business.setMozo(mozo);
		for (ComandaEntity comandaEntity : entity.getComandas()) {
			Comanda comanda = new Comanda();
			comanda.setId(comandaEntity.getId());
			comanda.setEstado(comandaEntity.getEstado());
			comanda.setCantidad(comandaEntity.getCantidad());
			final Plato plato = getPlatoDAO().get(
					comandaEntity.getPlato().getId());
			comanda.setPlato(plato);
			business.getComandas().add(comanda);
		}
		return business;
	}

	@Override
	public List<Pedido> buscarPedidosSinFactura(final Long localId) {
		return execute(new Query<List<Pedido>>() {
			@Override
			public List<Pedido> inTransaction(Session session)
					throws PersistenceException {
				@SuppressWarnings("unchecked")
				final List<PedidoEntity> results = 
						session.getNamedQuery("pedido.sinFacturar")
								.setLong("localId", localId)
								.list();
				return toBusiness(results);
			}
		});
	}
	
	@Override
	public List<Pedido> buscarPedidosActivos(final Long salonId) {
		return execute(new Query<List<Pedido>>() {
			@Override
			public List<Pedido> inTransaction(Session session)
					throws PersistenceException {
				@SuppressWarnings("unchecked")
				final List<PedidoEntity> results = 
						session.getNamedQuery("pedido.byEstadoBySalon")
								.setLong("salonId", salonId)
								.setBoolean("estado", true)
								.list();
				return toBusiness(results);
			}
		});
	}
	

}
